/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	OutputMerger.h
*
*	Description -	
*
*	Comments	-	
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	06/01/2012	-	Creation of this file
**************************************************************************************/
#ifndef PSX_OUTPUT_MERGER_STAGE_H_
#define PSX_OUTPUT_MERGER_STAGE_H_

#include "PulseSTD.h"
#include "GraphicsInfrastructure.h"
#include "IPipelineStage.h"
#include "Color.h"

namespace Pulse
{
	struct OutputMergerState
	{
		OutputMergerState( void );

		void ClearState( void );

		BlendState			*m_pBlendState;
		FLOAT				m_blendFactors[4]; // rgba
		UINT				m_sampleMask;
		DepthStencilState	*m_pDepthStencilState;
		UINT				m_stencilRef;
		ShaderResource		*m_pRenderTargets[PSX_NUM_RENDER_TARGET_SLOT];
		ShaderResource		*m_pDepthStencil;
		
		ID3D11RenderTargetView	*m_pD3DRenderTargets[PSX_NUM_RENDER_TARGET_SLOT];
	};

	class OutputMergerStage : public IPipelineStage
	{
	public:

		OutputMergerStage( void );

		virtual ~OutputMergerStage( void );

		virtual EPipelineStage::Type GetType( void ) { return EPipelineStage::OutputMerger; }

		////////////////////// CACHING METHODS /////////////////////////
		void SetBlendState( BlendState *pBlendState );

		void SetBlendFactors( FLOAT r, FLOAT g, FLOAT b, FLOAT a );

		void SetBlendFactors( const FLOAT *pBlendFactors );

		void SetSampleMask( const UINT sampleMask );

		void SetDepthStencilState( DepthStencilState *pDepthStencilState );

		void SetStencilRef( UINT ref );

		void SetDepthStencil( ShaderResource *pRT );

		void SetRenderTarget( const UINT slot, ShaderResource *pRT );

		void SetRenderTarget( const UINT numTargets, ShaderResource **pRTS );

		const UINT GetNumRenderTargets( void ) const;

		virtual void ClearStates( void );

		///////////////////////// BINDING METHODS /////////////////////

		void BindBlendState( void );

		void BindDepthStencilState( void );

		void BindRenderTargets( void );

		// This method calls all the binding methods above
		virtual void BindStates( void );

		////////////////////// IMMEDIATE METHODS /////////////////

		void ClearBuffers( const Color *pClearColor, FLOAT depth = 1.0f, UINT stencil = 0 );

	private:

		OutputMergerState m_desiredState;
		OutputMergerState m_currentState;

	};
}

#endif /* PSX_OUTPUT_MERGER_STAGE_H_ */